<template>
  <div
    class="h-pagination"
    :class="{
      'is-background': background,
      'h-pagination--small': size == 'small',
      'h-pagination--large': size == 'large',
    }"
  >
    <prev
      :disabled
      :current-page="currentPageBridge"
      :prev-text="prevText"
      :prev-icon="prevIcon"
      @click="prevEvent"
    ></prev>
    <pager
      :disabled
      :current-page="currentPageBridge"
      :page-count="pageCountBridge"
      :pager-count="pagerCount"
      @change="handleCurrentChange"
    ></pager>
    <next
      :disabled
      :current-page="currentPageBridge"
      :page-count="pageCountBridge"
      :next-text="nextText"
      :next-icon="nextIcon"
      @click="nextEvent"
    ></next>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from "vue";
import Prev from "./Prev/Prev.vue";
import Next from "./Next/Next.vue";
import Pager from "./Pager/Pager.vue";
import type { PaginationProps, PaginationEmits } from "./types";

const {
  disabled,
  defaultCurrentPage = 1,
  total,
  pageCount,
  defaultPageSize = 10,
  prevText,
  prevIcon,
  pagerCount = 7,
  nextText,
  nextIcon,
} = defineProps<PaginationProps>();
const currentPage = defineModel<number>("currentPage");
const pageSize = defineModel<number>("pageSize");
const emit = defineEmits<PaginationEmits>();

// 类型谓词函数 v类型检查和类型缩小
const isAbsent = (v: unknown): v is undefined => typeof v !== "number";
const innerCurrentPage = ref(
  isAbsent(defaultCurrentPage) ? 1 : defaultCurrentPage
);
const innerPageSize = ref(isAbsent(defaultPageSize) ? 10 : defaultPageSize);

// 每页显示条目个数
const pageSizeBridge = computed({
  get() {
    return isAbsent(pageSize.value) ? innerPageSize.value : pageSize.value;
  },
  set(v: number) {
    if (isAbsent(pageSize.value)) {
      innerPageSize.value = v;
    } else {
      emit("sizeChange", v);
    }
  },
});

// 总页数
const pageCountBridge = computed<number>(() => {
  let pageCount1 = 0;
  if (!isAbsent(pageCount)) {
    pageCount1 = pageCount;
  } else if (!isAbsent(total)) {
    pageCount1 = Math.max(1, Math.ceil(total / Number(pageSizeBridge.value)));
  }
  return pageCount1;
});

// 当前页
const currentPageBridge = computed<number>({
  get() {
    return isAbsent(currentPage.value)
      ? innerCurrentPage.value
      : currentPage.value;
  },
  set(v) {
    let newCurrentPage = v;
    if (v < 1) {
      newCurrentPage = 1;
    } else if (v > pageCountBridge.value) {
      newCurrentPage = pageCountBridge.value;
    }
    if (isAbsent(currentPage.value)) {
      innerCurrentPage.value = newCurrentPage;
    } else {
      emit("currentChange", newCurrentPage);
    }
  },
});

// 上一页点击事件
function prevEvent() {
  if (disabled) return;
  currentPageBridge.value -= 1;
  emit("prevClick", currentPageBridge.value);
}

// 下一页点击事件
function nextEvent() {
  if (disabled) return;
  currentPageBridge.value += 1;
  emit("nextClick", currentPageBridge.value);
}

function handleCurrentChange(val: number) {
  currentPageBridge.value = val;
}

watch(pageCountBridge, (val) => {
  if (currentPageBridge.value > val) currentPageBridge.value = val;
});

watch(
  [currentPageBridge, pageSizeBridge],
  (value) => {
    emit("change", ...value);
  },
  { flush: "post" }
);
</script>

<style scoped>
@import url(./style.css);
</style>
